package com.fjnu.dao.impl;

import com.fjnu.annotation.NPECatch;
import com.fjnu.dao.UserDao;
import com.fjnu.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.sql.*;
import java.time.LocalDateTime;

/**
 * @desc:
 * @author:
 * @date:
 */
@Repository
@NPECatch
public class UserDaoImpl implements UserDao {
    /**
     * 注入 connection Bean,利用connection bean来完成对数据库的操作
     */
    @Autowired
    private Connection connection;

    @Override
    public int insert(User user) {
        String sql = "INSERT INTO user (user_id, username, password, salt,nickname, email, phone,sex,age,img, status, create_time, update_time,last_login_time) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, user.getUserId());
            pstmt.setString(2, user.getUsername());
            pstmt.setString(3, user.getPassword());
            pstmt.setString(4, user.getSalt());
            pstmt.setString(5, user.getNickname());
            pstmt.setString(6, user.getEmail());
            pstmt.setString(7, user.getPhone());
            pstmt.setInt(8, user.getSex());
            pstmt.setInt(9, user.getAge());
            pstmt.setString(10, user.getImg());
            pstmt.setInt(11, user.getStatus());
            pstmt.setObject(12, user.getCreateTime() != null ? user.getCreateTime() :  LocalDateTime.now());
            pstmt.setObject(13, user.getUpdateTime() != null ? user.getUpdateTime() :  LocalDateTime.now());
            pstmt.setObject(14, user.getLastLoginTime() != null ? user.getLastLoginTime() :  LocalDateTime.now());
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("插入用户失败", e);
        }
    }

    @Override
    public int delete(String userId) {
        String sql = "DELETE FROM user WHERE user_id = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, userId);
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("删除用户失败", e);
        }
    }

    @Override
    public int updateById(String userId, User newUser) {
        String sql = "UPDATE user SET nickname = ?, email = ?, phone = ?, status = ?, update_time = ? " +
                "WHERE user_id = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, newUser.getNickname());
            pstmt.setString(2, newUser.getEmail());
            pstmt.setString(3, newUser.getPhone());
            pstmt.setInt(4, newUser.getStatus());
            pstmt.setObject(5, LocalDateTime.now());
            pstmt.setString(6, userId);
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("更新用户信息失败", e);
        }
    }

    @Override
    public int updatePasswordById(String userId, String oldPassword, String newPassword) {
        String sql = "UPDATE user SET password = ?, update_time = ? " +
                "WHERE user_id = ? AND password = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, newPassword);
            pstmt.setObject(2, LocalDateTime.now());
            pstmt.setString(3, userId);
            pstmt.setString(4, oldPassword);
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("更新密码失败", e);
        }
    }

    @Override
    public User selectById(String userId) {
        String sql = "SELECT * FROM user WHERE user_id = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, userId);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapResultSetToUser(rs);
                }
                return null;
            }
        } catch (SQLException e) {
            throw new RuntimeException("根据ID查询用户失败", e);
        }
    }

    @Override
    public User selectByUsernameAndPassword(String username, String password) {
        String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, username);
            pstmt.setString(2, password);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapResultSetToUser(rs);
                }
                return null;
            }
        } catch (SQLException e) {
            throw new RuntimeException("根据用户名和密码查询用户失败", e);
        }
    }

    @Override
    public int selectCount() {
        String sql = "SELECT COUNT(*) FROM user";
        try (PreparedStatement pstmt = connection.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {
            if (rs.next()) {
                return rs.getInt(1);
            }
            return 0;
        } catch (SQLException e) {
            throw new RuntimeException("统计用户数量失败", e);
        }
    }

    /**
     * 将ResultSet映射到User对象的辅助方法
     */
    private User mapResultSetToUser(ResultSet rs) throws SQLException {
        User user = new User();
        user.setUserId(rs.getString("user_id"));
        user.setUsername(rs.getString("username"));
        user.setPassword(rs.getString("password"));
        user.setSalt(rs.getString("salt"));
        user.setNickname(rs.getString("nickname"));
        user.setEmail(rs.getString("email"));
        user.setPhone(rs.getString("phone"));
        user.setSex(rs.getInt("sex"));
        user.setAge(rs.getInt("age"));
        user.setImg(rs.getString("img"));
        user.setStatus(rs.getInt("status"));
        Timestamp createTime = rs.getTimestamp("create_time");
        Timestamp updateTime = rs.getTimestamp("update_time");
        Timestamp lastLoginTime = rs.getTimestamp("last_login_time");
        user.setCreateTime(createTime != null ? createTime.toLocalDateTime() : null);
        user.setUpdateTime(updateTime != null ? updateTime.toLocalDateTime() : null);
        user.setLastLoginTime(lastLoginTime != null ? lastLoginTime.toLocalDateTime() : null);
        return user;
    }
}